package app.controllers;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import app.annotations.Public;
import app.models.Consulta;
import app.models.Especialidade;
import app.models.Funcionario;
import app.models.ParametroSistema;
import app.models.SubEspecialidade;
import app.models.enums.DiasSemana;
import app.models.enums.StatusBiometria;
import app.models.enums.StatusConsulta;
import app.models.enums.TipoConsulta;
import app.services.BiometriaTemplateService;
import app.services.CHService;
import app.services.ConsultaService;
import app.services.ConvenioService;
import app.services.EspecialidadeService;
import app.services.FuncionarioService;
import app.services.PacienteService;
import app.services.ParametroSistemasService;
import app.services.SubEspecialidadeService;
import app.session.UserSession;
import app.util.DateUtils;
import br.com.caelum.vraptor.Get;
import br.com.caelum.vraptor.Post;
import br.com.caelum.vraptor.Resource;
import br.com.caelum.vraptor.Result;
import br.com.caelum.vraptor.Validator;
import br.com.caelum.vraptor.validator.ValidationMessage;

@Resource
public class ConsultaController extends Controller {

	private final Result result;
	private final ConsultaService service;
	private final PacienteService pacienteService;
	private final FuncionarioService funcionarioService;
	private final EspecialidadeService especialidadeService;
	private final SubEspecialidadeService subEspecialidadeService;
	private final ConvenioService convenioService;
	private final UserSession userSession;
	private final Validator validator;
	private final HttpServletRequest request;
	private final BiometriaTemplateService biometriaService;
	private final CHService chService;
	private final HttpServletResponse response;
	private final ParametroSistemasService parametroSistemasService;
	
	public ConsultaController(Result result,
			ConsultaService service, Validator validator,
			PacienteService pacienteService,
			FuncionarioService funcionarioService,
			EspecialidadeService especialidadeService,
			SubEspecialidadeService subEspecialidadeService,
			ConvenioService convenioService,
			UserSession userSession,
			HttpServletRequest request,
			BiometriaTemplateService biometriaService,
			CHService chService,
			HttpServletResponse response,
			ParametroSistemasService parametroSistemasService) {

		this.result = result;
		this.service = service;
		this.validator = validator;
		this.pacienteService = pacienteService;
		this.funcionarioService = funcionarioService;
		this.especialidadeService = especialidadeService;
		this.subEspecialidadeService = subEspecialidadeService;
		this.convenioService = convenioService;
		this.userSession = userSession;
		this.request = request;
		this.biometriaService = biometriaService;
		this.chService = chService;
		this.response = response;
		this.parametroSistemasService = parametroSistemasService;
	}
	
	
	@Get("/consultas")
	public void index() {
		
		Integer month = DateUtils.getMesAtual();
		Integer year = DateUtils.getAnoAtual();
		
		this.result.include("today", DateUtils.getDiaAtual());
		this.result.include("month", month);
		this.result.include("year", year);
		this.result.include("monthName", DateUtils.getMonthName(DateUtils.getMesAtual()));
		
		month -= 1;
		
		// relação consultas/dia
		this.result.include("consultasDiarias", service.findConsultasInDayOnMonth(null, month, year));
		
		// primeiro dia da semana do mês atual
		this.result.include("firstWeekDay", service.findFirstWeekDay(null, null));
		
		// quantidade de dias do mês atual
		this.result.include("lastMonthDay", service.findLastMonthDay(null, null));
		
		// todos os dias da semana
		this.result.include("weekDays", DiasSemana.values());
	}
	
	
	@Get("/consultas/{month}/{year}")
	public void index(Consulta consulta, Integer month, Integer year) {
		
		this.result.include("tipos", TipoConsulta.values());
		this.result.include("month", month);
		this.result.include("year", year);
		this.result.include("monthName", DateUtils.getMonthName(month));
		
		// Limpar filtros da tela
		if (null != request.getParameter("submit")) {
			if (request.getParameter("submit").equals("Limpar")) {
				consulta = new Consulta();
			}
		}
		
		// Calendar inicia o ano com primeiro mês = 0.
		month -= 1;
		
		// relação consultas/dia
		consulta.setStatus(null);
		this.result.include("consultasDiarias", service.findConsultasInDayOnMonth(consulta, month, year));
		
		// primeiro dia da semana do mês/ano atual
		this.result.include("firstWeekDay", service.findFirstWeekDay(month, year));
		
		// quantidade de dias do mês/ano atual
		this.result.include("lastMonthDay", service.findLastMonthDay(month, year));
		
		// todos os dias da semana
		this.result.include("weekDays", DiasSemana.values());

		// filtros do calendário
		this.result.include("consulta", consulta);
		
		if (consulta.getTipo() == TipoConsulta.PARTICULAR) {
			List<Especialidade> especialidades = especialidadeService.findAllOrdered();
			
			if (especialidades.isEmpty()) {
				validator.add(new ValidationMessage("Necessário " +
						"<a title=\"Clique aqui para Cadastrar Especialidade Particular\" " +
						"href=\"" + handleMe(request) + "/especialidades/new\">Cadastrar uma Especialidade Particular</a> " +
								"para que possa ser utilizado o filtro de Especialidades", "erro"));
			} else {
				this.result.include("especialidades", especialidades);
			}
		} else if (consulta.getTipo() == TipoConsulta.CONVENIO) {
			List<SubEspecialidade> subEspecialidades = subEspecialidadeService.findAllOrdered();
			
			if (subEspecialidades.isEmpty()) {
				validator.add(new ValidationMessage("Necessário " +
						"<a title=\"Clique aqui para Cadastrar Especialidade Convênio\" " +
						"href=\"" + handleMe(request) + "/subEspecialidades/new\">Cadastrar uma Especialidade Convênio</a> " +
								"para que possa ser utilizado o filtro de Especialidades", "erro"));
			} else {
				this.result.include("subEspecialidades", subEspecialidades);
			}
		}
		
		List<Funcionario> especialistas = funcionarioService.findAllOrdered();
		
		if (especialistas.isEmpty()) {
			validator.add(new ValidationMessage("Necessário " +
					"<a title=\"Clique aqui para Cadastrar Especialista\" " +
					"href=\"" + handleMe(request) + "/funcionarios/new\">Cadastrar um Especialista</a> " +
							"para que possa ser utilizado o filtro de Especialistas", "erro"));
		} else {
			if (null != consulta.getEspecialidade()) {
				this.result.include("especialistas", funcionarioService.findEspecialistasByEspecialidade(consulta.getEspecialidade().getId()));
			} else if (null != consulta.getSubEspecialidade()) {
				this.result.include("especialistas", funcionarioService.findEspecialistasByEspecialidade(Long.valueOf(consulta.getSubEspecialidade().getEspecialidade().getId())));
			} else {
				this.result.include("especialistas", especialistas);
			}
		}
		
		validator.onErrorRedirectTo(this).sendErrorsToScreen(consulta, null, month, year);
	}
	
	
	@Get("/consultas/{mDay}/{month}/{year}")
	public void formHorario(Consulta consulta, Integer mDay, Integer month, Integer year) {
		
		this.result.include("tipos", TipoConsulta.values());
		this.result.include("mDay", mDay);
		this.result.include("month", month);
		this.result.include("year", year);
		this.result.include("weekDayName", DateUtils.getWeekDayName(DateUtils.getWeekDay(mDay, month, year)));
		this.result.include("monthName", DateUtils.getMonthName(month));
		
		// Limpar filtros da tela
		if (null != request.getParameter("submit")) {
			if (request.getParameter("submit").equals("Limpar")) {
				consulta = new Consulta();
			}
		}
		
		this.result.include("consultas", service.findConsultasByFilters(consulta, mDay, (month - 1), year));
		
		consulta.setData(year + "-" + DateUtils.formatMonth(month) + "-" + mDay);
		this.result.include("consulta", consulta);
		
		if (consulta.getTipo() == TipoConsulta.PARTICULAR) {
			List<Especialidade> especialidades = especialidadeService.findAllOrdered();
			
			if (especialidades.isEmpty()) {
				validator.add(new ValidationMessage("Necessário " +
						"<a title=\"Clique aqui para Cadastrar Especialidade Particular\" data-toggle=\"modal\" data-dismiss=\"modal\" aria-hidden=\"true\" " +
						"href=\"" + handleMe(request) + "/especialidades/new\">Cadastrar uma Especialidade Particular</a> " +
								"para que possa ser utilizado o filtro de Especialidades", "erro"));
			} else {
				this.result.include("especialidades", especialidades);
			}
		} else if (consulta.getTipo() == TipoConsulta.CONVENIO) {
			List<SubEspecialidade> subEspecialidades = subEspecialidadeService.findAllOrdered();
			
			if (subEspecialidades.isEmpty()) {
				validator.add(new ValidationMessage("Necessário " +
						"<a title=\"Clique aqui para Cadastrar Especialidade Convênio\" data-toggle=\"modal\" data-dismiss=\"modal\" aria-hidden=\"true\" " +
						"href=\"" + handleMe(request) + "/subEspecialidades/new\">Cadastrar uma Especialidade Convênio</a> " +
								"para que possa ser utilizado o filtro de Especialidades", "erro"));
			} else {
				this.result.include("subEspecialidades", subEspecialidades);
			}
		}
		
		List<Funcionario> especialistas = funcionarioService.findAllOrdered();
		
		if (especialistas.isEmpty()) {
			validator.add(new ValidationMessage("Necessário " +
					"<a title=\"Clique aqui para Cadastrar Especialista\" data-toggle=\"modal\" data-dismiss=\"modal\" aria-hidden=\"true\" " +
					"href=\"" + handleMe(request) + "/funcionarios/new\">Cadastrar um Especialista</a> " +
							"para que possa ser utilizado o filtro de Especialistas", "erro"));
		} else {
			if (null != consulta.getIdEspecialidade()) {
				Especialidade especialidade = especialidadeService.find(consulta.getIdEspecialidade().longValue());
				
				this.result.include("especialistas", funcionarioService.findEspecialistasByEspecialidade(especialidade.getId()));
			} else if (null != consulta.getIdSubEspecialidade()) {
				SubEspecialidade subEspecialidade = subEspecialidadeService.find(consulta.getIdSubEspecialidade().longValue());
				
				this.result.include("especialistas", funcionarioService.findEspecialistasByEspecialidade(Long.valueOf(subEspecialidade.getEspecialidade().getId())));
			} else {
				this.result.include("especialistas", especialistas);
			}
		}
		
		validator.onErrorRedirectTo(this).sendErrorsToScreen(consulta, mDay, month, year);
	}
	
	
	public void sendErrorsToScreen(Consulta consulta, Integer mDay, Integer month, Integer year) {
		
		this.result.include("mDay", mDay);
		this.result.include("month", month);
		this.result.include("year", year);
		this.result.include("consulta", consulta);
		
		if (null != mDay) {
			this.result.forwardTo("/WEB-INF/jsp/consulta/formHorario.jsp");
		} else {
			this.result.forwardTo("/WEB-INF/jsp/consulta/index.jsp");
		}
	}
	
	
	@Get("/consultas/calendario/{action}/{year}")
	public void index(String action, Integer year) {
		if (action.equals("proximo")) {
			this.result.include("year", year + 1);
		} else if (action.equals("anterior")) {
			this.result.include("year", year - 1);
		}
	}
	
	@Get("/consultas/new/{month}/{year}")
	public void form(Consulta consulta, Integer month, Integer year) {
		
		if (null != request.getParameter("filterPaciente")) {
			this.result.include("filterPaciente", request.getParameter("filterPaciente").toString());
			this.result.include("pacientesFilter", pacienteService.findPacientesByFilter(request.getParameter("filterPaciente").toString()));
			
			if (null != request.getParameter("aux")) {
				if (request.getParameter("aux").equals("filterPaciente")) {
					this.result.include("aux", request.getParameter("aux").toString());
					
					if (request.getParameter("filterPaciente").equals("")) {
						this.result.nothing();
					} else {
						this.result.of(this).pacienteFilter();
					}
				} else if (request.getParameter("aux").equals("filterDefault")) {
					
					this.result.include("aux", request.getParameter("aux").toString());
				}
			}
		}
		
		this.result.include("month", month);
		this.result.include("year", year);
		this.result.include("userSession", this.userSession.getUser());
		
		if (null != request.getParameter("form")) {
			if (request.getParameter("form").equals("modalForm")) {
				if(consulta.getIdEspecialista() != null && consulta.getIdEspecialista() != 0){
					Funcionario especialista = funcionarioService.find(consulta.getIdEspecialista().longValue());
					consulta.setEspecialista(especialista);
					consulta.setIdEspecialista(especialista.getId().intValue());
				}
				
				if (consulta.isFLagPagou()) {
					consulta.setDataPagamento(DateUtils.getDataAtual());
					consulta.setStatus(StatusConsulta.PAGA);
				}
			} else {
				this.result.include("tipos", TipoConsulta.values());
				this.result.include("convenios", convenioService.findAll());
				this.result.include("pacientes", pacienteService.findAllOrderedWithoutMax());
				
				if (consulta.getTipo() == TipoConsulta.PARTICULAR) {
					List<Especialidade> especialidades = especialidadeService.findAllOrdered();
					
					if (especialidades.isEmpty()) {
						validator.add(new ValidationMessage("Necessário " +
								"<a title=\"Clique aqui para Cadastrar Especialidade Particular\" data-toggle=\"modal\" data-dismiss=\"modal\" aria-hidden=\"true\" " +
								"href=\"" + handleMe(request) + "/especialidades/new\">Cadastrar uma Especialidade Particular</a> ", "erro"));
					} else {
						this.result.include("especialidades", especialidades);
					}
				} else if (consulta.getTipo() == TipoConsulta.CONVENIO) {
					List<SubEspecialidade> subEspecialidades = subEspecialidadeService.findAllOrdered();
					
					if (subEspecialidades.isEmpty()) {
						validator.add(new ValidationMessage("Necessário " +
								"<a title=\"Clique aqui para Cadastrar Especialidade Convênio\" data-toggle=\"modal\" data-dismiss=\"modal\" aria-hidden=\"true\" " +
								"href=\"" + handleMe(request) + "/subEspecialidades/new\">Cadastrar uma Especialidade Convênio</a> ", "erro"));
					} else {
						this.result.include("subEspecialidades", subEspecialidades);
					}
				}
			}
		}
		
		List<Funcionario> especialistas = funcionarioService.findAllOrdered();
		
		if (especialistas.isEmpty()) {
			validator.add(new ValidationMessage("Necessário " +
					"<a title=\"Clique aqui para Cadastrar Especialista\" data-toggle=\"modal\" data-dismiss=\"modal\" aria-hidden=\"true\" " +
					"href=\"" + handleMe(request) + "/funcionarios/new\">Cadastrar um Especialista</a> ", "erro"));
		} else {
			
			if (null != consulta.getIdEspecialidade()) {
				Especialidade especialidade = especialidadeService.find(consulta.getIdEspecialidade().longValue());
				
				consulta.setValor(especialidade.getValor());
				
				especialistas = funcionarioService.findEspecialistasByEspecialidade(especialidade.getId());
				
				if (especialistas.isEmpty()) {
					validator.add(new ValidationMessage("Necessário " +
						"<a title=\"Clique aqui para Cadastrar Especialista\" data-toggle=\"modal\" data-dismiss=\"modal\" aria-hidden=\"true\" " +
						"href=\"" + handleMe(request) + "/funcionarios/new\">Cadastrar um Especialista</a> para essa Especialidade", "erro"));
				} else {
					this.result.include("especialistas", especialistas);
				}
				
			} else if (null != consulta.getIdSubEspecialidade()) {
				SubEspecialidade subEspecialidade = subEspecialidadeService.find(consulta.getIdSubEspecialidade().longValue());
				
				consulta.setValor(subEspecialidade.getValor());
				
				especialistas = funcionarioService.findAllEspecialistasByEspecialidade(subEspecialidade.getEspecialidade().getId().intValue());
				
				if (especialistas.isEmpty()) {
					validator.add(new ValidationMessage("Necessário " +
							"<a title=\"Clique aqui para Cadastrar Especialista\" data-toggle=\"modal\" data-dismiss=\"modal\" aria-hidden=\"true\" " +
							"href=\"" + handleMe(request) + "/funcionarios/new\">Cadastrar um Especialista</a> para essa Especialidade", "erro"));
				} else {
					this.result.include("especialistas", especialistas);
				}
				
			} else {
				consulta.setValor(0.0);
				
				this.result.include("especialistas", especialistas);
			}
		}

		consulta.setIdSecretaria(userSession.getUser().getId().intValue());
		
		this.result.include("consulta", consulta);
		
		if (null != request.getParameter("submit")) {
			if (request.getParameter("submit").equals("Agendar")) {
				validator.validate(consulta);
				validator.onErrorUsePageOf(this).form(consulta, month, year);
			} else if (!request.getParameter("submit").equals("Marcar Consulta") && !request.getParameter("submit").equals("Agendar")) {
				validator.validate(consulta);
				validator.onErrorForwardTo(this).form(consulta.getId());
			}
			
			if (request.getParameter("submit").equals("Agendar") || request.getParameter("submit").equals("Iniciar")) {
				this.result.forwardTo(this).save(consulta, month, year);
			} else if (request.getParameter("submit").equals("Confirmar")) {
				this.result.forwardTo(this).iniciaConsulta(consulta);
			} else if (!request.getParameter("submit").equals("Marcar Consulta") && !request.getParameter("submit").equals("Agendar")) {
				this.result.forwardTo(this).fields();
			}
			
		} else if (null != request.getParameter("hasFilter")) {
			if (request.getParameter("hasFilter").equals("Sim")) {
				validator.validate(consulta);
				validator.onErrorForwardTo(this).fields();
				this.result.forwardTo(this).fields();
			}
		}
		
		validator.onErrorUsePageOf(this).form(consulta, month, year);
		
	}
	
	
	@Get("/consultas/save/{month}/{year}")
	public void save(Consulta consulta, Integer month, Integer year) {
		
		String horaFinal = consulta.getHoraFinal().replace(":", "");
		
		if(horaFinal.length() == 5){
			horaFinal = "0" + horaFinal;
		}
		
		String horaInicial = consulta.getHoraInicial().replace(":", "");
		
		if(horaInicial.length() == 5){
			horaInicial = "0" + horaInicial;
		}
		
		if(consulta.getEspecialidade() != null ){
			if(!consulta.getEspecialidade().getNome().equals("FISIOTERAPIA")){
				if (service.verifyEspecialistasConsults(consulta)){
					
					validator.add(new ValidationMessage("Especialista não está com esse horário disponível", "erro"));
				}
			}
		} else {
			if(consulta.getSubEspecialidade() != null){
				if(!consulta.getSubEspecialidade().getEspecialidade().getNome().equals("FISIOTERAPIA")){
					if (service.verifyEspecialistasConsults(consulta)){
						
						validator.add(new ValidationMessage("Especialista não está com esse horário disponível", "erro"));
					}
				}
			}
		}
		
		if (null != consulta.getTipo()) {
			if (consulta.getTipo().equals(TipoConsulta.CONVENIO)) {
				if (null == consulta.getIdConvenio()) {
					
					validator.add(new ValidationMessage("Necessário definir Convênio", "erro"));
				}
			}
		}
		
			try {
				if(DateUtils.getHora(horaFinal) == DateUtils.getHora(horaInicial)){
					validator.add(new ValidationMessage("A hora inicial não pode ser igual a hora final", "erro"));
				}
				
				if(DateUtils.getHora(horaFinal) < DateUtils.getHora(horaInicial) ){
					validator.add(new ValidationMessage("A hora inicial não pode ser depois da hora final", "erro"));
				}
				
				/*if(DateUtils.convertDataStrToDate(consulta.getData()).before(DateUtils.convertDataStrToDate(DateUtils.getDataAtual()))){
					validator.add(new ValidationMessage("A data da consulta não pode ser anterior à data atual", "erro"));
				}*/
				
				/*
				 else {
					if(DateUtils.convertDataStrToDate(consulta.getData()).compareTo(DateUtils.convertDataStrToDate(DateUtils.getDataAtual())) < 0){
						if(DateUtils.getHora(horaFinal) < new Date().getHours()){
							validator.add(new ValidationMessage("A data da consulta não pode ser anterior à data atual", "erro"));
						}
					}
				}
				*/
			} catch (Exception e) {
				validator.add(new ValidationMessage("Erro ao validar a hora e a data da consulta", "erro"));
				e.getStackTrace();
			}
			
		if(service.verifyLatePayments(consulta.getIdPaciente())){
			validator.add(new ValidationMessage("O paciente já possui 3 consultas ainda não pagas. " +
					"Nao é possível realizar outra consulta enquanto as consultas em aberto não forem pagas.", "erro"));
		}
		
		if(consulta.isFLagPagou()) {
			consulta.setDataPagamento(DateUtils.getDataAtual());
			consulta.setStatus(StatusConsulta.PAGA);
		} else {
			consulta.setStatus(StatusConsulta.MARCADA);
		}
		
		if(consulta.getDesconto() != null){
			consulta.setValor(consulta.getValor() - consulta.getDesconto());
		} else {
			consulta.setValor(consulta.getValor());
		}
		
		validator.onErrorForwardTo(this).form();
		
		service.create(consulta);
		
		if (null != request.getParameter("typeNewConsulta") && !request.getParameter("typeNewConsulta").isEmpty()) {
			if(Integer.valueOf(request.getParameter("typeNewConsulta")) == 2){ 
				this.result.include("consulta", consulta);
				this.result.forwardTo("/WEB-INF/jsp/consulta/iniciaConsulta.jsp");
			} else {
				this.result.forwardTo(this).index();
			}
		} else {
			this.result.forwardTo(this).index();
		}
		
	}
	
	
	public void form(){}
	
	
	@Get("/consultas/search")
	public void search(Consulta consulta) {}
	
	
	@Post("/consultas/update")
	public void update(Consulta consulta) {
		validator.validate(consulta);
		validator.onErrorUsePageOf(this).form(consulta.getId());
		service.update(consulta);
		
		this.result.redirectTo(this).index();
	}
	
	@Get("/consultas/{id}/edit")
	public void form(Long id) {
		Consulta consulta = service.find(id);
		
		this.result.include("consulta", consulta);
		
		this.result.include("tipos", TipoConsulta.values());
		this.result.include("convenios", convenioService.findAll());
		this.result.include("pacientes", pacienteService.findAllOrderedWithoutMax());
		
		if (consulta.getTipo() == TipoConsulta.CONVENIO) {
			this.result.include("especialidades", subEspecialidadeService.findAllOrdered());
			this.result.include("especialistas", funcionarioService.findAllEspecialistasByEspecialidade(consulta.getSubEspecialidade().getEspecialidade().getId().intValue()));
		} else {
			this.result.include("especialidades", especialidadeService.findAllOrdered());
			this.result.include("especialistas", funcionarioService.findEspecialistasByEspecialidade(consulta.getIdEspecialidade().longValue()));
		}
		
	}
	
	
	@Get("/consultas/updateEspecialista/{id}")
	public void updateEspecialista(Long id, Long especialistaId) {
		
		Consulta consulta = service.find(id);
		consulta.setEspecialista(funcionarioService.find(especialistaId));
		
		validator.validate(consulta);
		validator.onErrorUsePageOf(this).form(consulta.getId());
		
		service.update(consulta);
		
		this.result.redirectTo(this).index();
	}
	
	@Get("/consultas/confirm/{id}")
	public void confirm(Long id) {
		
		Consulta consulta = service.find(id);
		List<Funcionario> especialistas = new ArrayList<Funcionario>();
		
		if (consulta.getTipo() == TipoConsulta.CONVENIO) {
			especialistas = funcionarioService.findEspecialistasByEspecialidade(Long.valueOf(consulta.getSubEspecialidade().getEspecialidade().getId()));
			
			this.result.include("especialistas", especialistas);
		} else if (consulta.getTipo() == TipoConsulta.PARTICULAR) {
			especialistas = funcionarioService.findEspecialistasByEspecialidade(consulta.getIdEspecialidade().longValue());
			
			this.result.include("especialistas", especialistas);
		} else {
			validator.add(new ValidationMessage("Consulta possui um status inválido", "erro"));
		}
		
		if (null == especialistas) {
			validator.add(new ValidationMessage("Não há Especialista cadastrado para essa Especialidade", "erro"));
		}
		
		if(service.verifyLatePayments(consulta.getIdPaciente())){
			validator.add(new ValidationMessage("Paciente possui 3 consultas não pagas. Só é possível iniciar uma nova após acertar as anteriores.", "erro"));
		}
		
		Date dataAtual = new Date();
		
		if(dataAtual.toString().equals(consulta.getData())){
			validator.add(new ValidationMessage("Uma consulta só pode ser REALIZADA na data em que ela foi MARCADA :" + consulta.getData().toString(), "erro"));
		}
		
		if(StatusConsulta.CANCELADA.equals(consulta.getStatus()) ||
				StatusConsulta.FINALIZADA.equals(consulta.getStatus()) ||
				StatusConsulta.REALIZADA.equals(consulta.getStatus())){
			validator.add(new ValidationMessage("Uma consulta só pode ser REALIZADA se estiver com status PAGA ou MARCADA", "erro"));
		}
		
//		if(StatusConsulta.ATRASADA.equals(consulta.getStatus())){
//			validator.add(new ValidationMessage("Essa consulta esta ATRASADA, não é mais possível realizá-la", "erro"));
//		}
		
		this.result.include("consulta", consulta);
		
		validator.onErrorForwardTo(this).form(id);
		
		this.result.forwardTo(this).show();
	}
	
	
	@Get("/consultas/confirm")
	public void confirm(Consulta consulta) {
		this.result.include("c", consulta);
	}
	
	@Public
	@Post("/consultas/compareBiometria")
	public void compareBiometria(Boolean verify, Integer idConsulta) {
		
		Consulta consulta = service.find(idConsulta.longValue());
		
		if(verify){
			consulta.setStatusBiometria(StatusBiometria.SIM);
			service.update(consulta);
		}
		
		this.result.nothing();
	}
	
	
	@Get("/consultas/start/{idConsulta}")
	public void start(Long idConsulta) {
		Consulta consulta = service.find(idConsulta);
		
		if(StatusBiometria.NAO.equals(consulta.getStatusBiometria())){
			validator.add(new ValidationMessage("A biometria nao foi verificada", "erro"));
		}
		
		if(!StatusConsulta.MARCADA.equals(consulta.getStatus()) && !StatusConsulta.PAGA.equals(consulta.getStatus())){
			validator.add(new ValidationMessage("Apenas uma consulta nao realizada pode ser iniciada.", "erro"));
		}
		
		if(consulta.isFLagPagou() || StatusConsulta.PAGA.equals(consulta.getStatus())){
			consulta.setStatus(StatusConsulta.FINALIZADA);
		} else {
			consulta.setStatus(StatusConsulta.REALIZADA);
		}
		
		validator.validate(consulta);
		validator.onErrorForwardTo(this).index();
		
		service.update(consulta);
		
		// IMPLEMENTAR: Gerar nota fiscal
		
		this.result.forwardTo(this).index();
	}
	
	
	@Post("/consultas/saveStart")
	public void saveStart(Consulta consulta) {
		validator.validate(consulta);
		validator.onErrorUsePageOf(this).index();
		
		service.create(consulta);
		
		this.result.include("idConsulta", consulta.getId());
	}
	
	
	public void fields() { }
	
	
	public void show() { }
	
	
	@Get("/consultas/pay/{idConsulta}/{mDay}/{month}/{year}")
	public void pay(Integer idConsulta, Integer mDay, Integer month, Integer year) {
		Consulta consulta = service.find(idConsulta.longValue());
		
		if(StatusConsulta.MARCADA.equals(consulta.getStatus())){
			consulta.setStatus(StatusConsulta.PAGA);
			consulta.setDataPagamento(DateUtils.getDataAtual());
		} else if(StatusConsulta.REALIZADA.equals(consulta.getStatus())){
			consulta.setStatus(StatusConsulta.FINALIZADA);
			consulta.setDataPagamento(DateUtils.getDataAtual());
		} else {
			validator.add(new ValidationMessage("O status atual dessa consulta não permite essa ação", "erro"));
		}
		
		this.service.update(consulta);
		
		validator.onErrorUsePageOf(this).formHorario(new Consulta(), mDay, month, year);
		
		this.result.forwardTo(this).formHorario(new Consulta(), mDay, month, year);
		
		// IMPLEMENTAR: Gerar nota fiscal - não deverá ser obrigatório
	}
	
	
	@Get("/consultas/cancel/{idConsulta}/{mDay}/{month}/{year}")
	public void cancel(Integer idConsulta, Integer mDay, Integer month, Integer year) {
		if(!StatusConsulta.MARCADA.equals(service.find(idConsulta.longValue()).getStatus()) && !StatusConsulta.PAGA.equals(service.find(idConsulta.longValue()).getStatus())){
			validator.add(new ValidationMessage("Apenas uma consulta ainda não realizada pode ser cancelada", "erro"));
		}
		
		// Adicionar regra para barrar o cancelamento da consulta se for efetuado o cancelamento em menos de 3 horas antes da consulta, nesse caso mudar o status para cancelada em cima da hora e devera constar que o paciente e devedor		Consulta consulta = this.service.find(idConsulta.longValue());
		Consulta consulta = this.service.find(idConsulta.longValue());
		consulta.setStatus(StatusConsulta.CANCELADA);
		
		validator.onErrorUsePageOf(this).formHorario(new Consulta(), mDay, month, year);
		
		this.result.forwardTo(this).formHorario(new Consulta(), mDay, month, year);
	}
	
	@Get("/iniciaBiometriaModal/{idConsulta}")
	public void iniciaConsulta(Consulta consulta){
		service.update(consulta);
		
		this.result.include("consulta", consulta);
	}
	
	@Post("/consultas/verifyPassword/{idConsulta}")
	public void senhaModal(String senha, Long idConsulta){
		Consulta consulta = service.find(idConsulta);
		
		ParametroSistema parametroSistema = parametroSistemasService.findByParam("SENHA_BIOMETRIA");
		
		if(parametroSistema != null){
			if(parametroSistema.getValor().equals(senha)){
				consulta.setStatusBiometria(StatusBiometria.SIM);
			} else {
				consulta.setStatusBiometria(StatusBiometria.NAO);
				validator.add(new ValidationMessage("A senha não confere com a cadastrada no sistema", "erro"));
			}
		} else {
			validator.add(new ValidationMessage("Falha ao verificar a senha do Sistema", "erro"));
		}
		
		this.result.include("consulta",consulta);
		
		validator.onErrorUsePageOf(this).iniciaConsulta(consulta);
		
		service.update(consulta);
		
		this.result.forwardTo(this).iniciaConsulta(consulta);
	}	
	
	@Post("/consultas/modalPagar/{id}/{mDay}/{month}/{year}")
	public void modalPagar(Long id, Integer mDay, Integer month, Integer year) {
		this.result.include("idConsulta", id);
		this.result.include("mDay", mDay);
		this.result.include("month", month);
		this.result.include("year", year);
	}
	
	
	@Post("/consultas/modalCancelar/{id}/{mDay}/{month}/{year}")
	public void modalCancelar(Long id, Integer mDay, Integer month, Integer year) {
		this.result.include("idConsulta", id);
		this.result.include("mDay", mDay);
		this.result.include("month", month);
		this.result.include("year", year);
	}
	
	@Get("/pacienteFilter")
	public void pacienteFilter() {}
	
}